/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package main;

import javax.script.ScriptEngine;
import javax.script.ScriptEngineManager;
import javax.script.ScriptException;

/**
 * 函数解析器 - 解析用户输入的函数表达式，支持三角函数
 */
public class FunctionParser {
    private static final ScriptEngine engine = new ScriptEngineManager().getEngineByName("JavaScript");
    
    static {
        // 预定义数学函数
        try {
            engine.eval("var sin = Math.sin; var cos = Math.cos; var tan = Math.tan;");
            engine.eval("var asin = Math.asin; var acos = Math.acos; var atan = Math.atan;");
            engine.eval("var sinh = Math.sinh; var cosh = Math.cosh; var tanh = Math.tanh;");
            engine.eval("var exp = Math.exp; var log = Math.log; var log10 = Math.log10;");
            engine.eval("var sqrt = Math.sqrt; var pow = Math.pow; var abs = Math.abs;");
            engine.eval("var PI = Math.PI; var E = Math.E;");
        } catch (ScriptException e) {
            System.err.println("数学函数初始化失败: " + e.getMessage());
        }
    }
    
    /**
     * 计算函数值
     * @param expression 函数表达式，如 "sin(x) + cos(y)" 或 "x*x + y"
     * @param x x值
     * @param y y值
     * @return 函数计算结果
     */
    public static double eval(String expression, double x, double y) {
        try {
            // 预处理表达式
            String processedExpr = preprocessExpression(expression);
            
            // 设置变量值
            engine.put("x", x);
            engine.put("y", y);
            
            Object result = engine.eval(processedExpr);
            return ((Number) result).doubleValue();
        } catch (ScriptException e) {
            throw new RuntimeException("函数解析错误: " + expression + ", 错误: " + e.getMessage());
        }
    }
    
    /**
     * 预处理表达式，确保变量替换正确
     */
    private static String preprocessExpression(String expression) {
        // 直接使用原表达式，JavaScript引擎可以直接处理
        String expr = expression;
        
        // 确保三角函数等有Math.前缀（如果用户没写）
        expr = expr.replaceAll("(?i)sin\\(", "Math.sin(")
                  .replaceAll("(?i)cos\\(", "Math.cos(")
                  .replaceAll("(?i)tan\\(", "Math.tan(")
                  .replaceAll("(?i)asin\\(", "Math.asin(")
                  .replaceAll("(?i)acos\\(", "Math.acos(")
                  .replaceAll("(?i)atan\\(", "Math.atan(")
                  .replaceAll("(?i)sinh\\(", "Math.sinh(")
                  .replaceAll("(?i)cosh\\(", "Math.cosh(")
                  .replaceAll("(?i)tanh\\(", "Math.tanh(")
                  .replaceAll("(?i)exp\\(", "Math.exp(")
                  .replaceAll("(?i)log\\(", "Math.log(")
                  .replaceAll("(?i)sqrt\\(", "Math.sqrt(")
                  .replaceAll("(?i)pow\\(", "Math.pow(")
                  .replaceAll("(?i)abs\\(", "Math.abs(");
        
        return expr;
    }
    
    /**
     * 验证函数表达式是否有效
     */
    public static boolean isValidFunction(String expression) {
        try {
            // 用多组测试值验证函数
            double[][] testValues = {
                {1.0, 1.0}, {0.0, 0.0}, {-1.0, 1.0}, {2.0, -2.0}, {0.5, 0.5}
            };
            
            for (double[] values : testValues) {
                double result = eval(expression, values[0], values[1]);
                if (Double.isNaN(result) || Double.isInfinite(result)) {
                    System.err.println("函数在 (" + values[0] + ", " + values[1] + ") 处返回无效值: " + result);
                    return false;
                }
            }
            return true;
        } catch (Exception e) {
            System.err.println("函数验证失败: " + expression + " - " + e.getMessage());
            return false;
        }
    }
    
    /**
     * 获取支持的函数列表
     */
    public static String getSupportedFunctions() {
        return "支持的函数: sin, cos, tan, asin, acos, atan, sinh, cosh, tanh, " +
               "exp, log, sqrt, pow, abs, 以及基本算术运算";
    }
}